﻿#include "DarkNet.h"
#include "JsModelProxy.h"
#include "MapColorModel.h"
#include "RoadLineModel.h"
#include "RoadSignModel.h"
#include "SmartCar.h"
#include "models/ColorModel.h"
#include "models/SoftMaxModel.h"
#include "models/YoloModel.h"
#include "utils/utils.h"
#ifdef __EMSCRIPTEN__
#include "EmscriptenAPI.h"
#endif

// void LabelMeConvertDarknet(const std::string &labelme_path, const std::string &darknet_path);
// LabelMeConvertDarknet("d:/workspace/data/test/images", "d:/workspace/data/test");

void train_yolo()
{
    auto model = std::make_shared<YoloModel>();
    model->LoadFromIniFile("D:/workspace/cpp/darknet/data/yolo/model_train");
    model->LoadDataSet();

    // model->Train();

    // auto trainer = std::make_shared<Trainer>();
    // trainer->LoadFromIniFile("D:/workspace/cpp/darknet/data/yolo/trainer");
    // trainer->Train();
}

// void predict_yolo()
// {
//     auto net = std::make_shared<Net>(false);
//     net->Load("D:/workspace/cpp/darknet/data/yolo/models/model.lastest");
//     net->Predict("D:/workspace/cpp/darknet/data/yolo/images/0001.jpg");
//     // net->Predict("D:/workspace/cpp/darknet/data/yolo/images/0002.jpg");
// }

// void test_distort()
// {
//     DataImage img;
//     img.Load("D:/workspace/cpp/darknet/data/yolo/images/0001.jpg");
//     img.RandomDistort();
//     img.Save("D:/workspace/cpp/darknet/data/yolo/images/0001_distort.jpg");
// }

// void predict_yolo_qrcode()
// {
//     auto trainer = std::make_shared<Trainer>();
//     trainer->LoadFromIniFile("D:/workspace/cpp/darknet/data/qrcode/yolo_trainer");
//     std::vector<std::string> img_paths = {
//         "D:/workspace/cpp/darknet/data/qrcode/images/3.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/4.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/5.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/6.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/7.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/8.png",
//         "D:/workspace/cpp/darknet/data/qrcode/images/9.png",
//     };
//     auto img_paths_size = img_paths.size();
//     for (int i = 0; i < img_paths_size; i++)
//     {
//         auto img_path     = img_paths[i];
//         auto results      = trainer->Predict(img_path);
//         auto out_img_path = (std::filesystem::path("D:/workspace/cpp/darknet/data/qrcode/debugs/images") / std::filesystem::path(img_path).filename()).string();
//         auto img          = std::make_shared<DataImage>();
//         img->Load(img_path);

//         auto size  = results->size();
//         auto datas = results->data();
//         auto index = 0;
//         while (index < size)
//         {
//             int x       = datas[index++];
//             int y       = datas[index++];
//             int width   = datas[index++];
//             int height  = datas[index++];
//             int classid = datas[index++];
//             auto prob   = datas[index++];
//             std::cout << x << "," << y << "," << width << "," << height << std::endl;
//             img->DrawRectangle(x - width / 2, y - height / 2, width, height, 1.0f, 0.0f, 0.0f);
//         }
//         img->Save(out_img_path);
//     }
// }

void generate_roadsign()
{
    auto model = JsColorModel::GetInstance();
    std::vector<std::string> paths;
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/01.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/left/30.png");

    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/30.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/right/01.jpg");

    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/30.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/01.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forword/02.jpg");

    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/01.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/02.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/03.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/04.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/05.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/stop/30.png");

    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/30.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/tunnel/01.jpg");

    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/01.jpg");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/10.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/15.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/20.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/25.png");
    paths.push_back("D:/workspace/cpp/darknet/data/roadsigns/images/forbid/30.png");
    auto paths_size = paths.size();
    for (auto i = 0; i < paths_size; i++)
    {
        auto path = std::filesystem::path(paths[i]);
        auto img  = std::make_shared<DataImage>();
        if (!img->Load(path.string()))
        {
            std::cout << "invalid path = " << path << std::endl;
            continue;
        }
        auto subimg = model->GetColorImage(img, model->GetRedClassifyIndex(), 0.2f);
        if (subimg == nullptr) return;
        subimg        = subimg->ScaleFill(100, 60);
        auto filename = path.filename();
        auto direname = path.parent_path().filename();
        subimg->Save("D:/workspace/cpp/darknet/data/roadsigns/images/" + direname.string() + "_" + filename.string());
    }
}

// void train_roadlines()
// {
//     auto trainer = std::make_shared<RoadLineTrainer>();
//     trainer->GetPathClassifyMap()->insert_or_assign("D:/workspace/cpp/darknet/data/roadlines/images/forword_left_01.jpg", "forword_left");
//     trainer->GetPathClassifyMap()->insert_or_assign("D:/workspace/cpp/darknet/data/roadlines/images/forword_right_01.jpg", "forword_right");
//     trainer->GetPathClassifyMap()->insert_or_assign("D:/workspace/cpp/darknet/data/roadlines/images/left_01.jpg", "left");
//     trainer->GetPathClassifyMap()->insert_or_assign("D:/workspace/cpp/darknet/data/roadlines/images/right_01.jpg", "right");
//     trainer->SetModelsPath("D:/workspace/cpp/darknet/data/roadlines/models");
//     trainer->LoadDataItems();
//     trainer->LoadNet();
//     trainer->ResetDataSet(trainer->GetDataSet());
//     trainer->DoEpoch();
//     trainer->DoEpoch();
// }

void test_colors()
{
    // auto img = std::make_shared<DataImage>();
    // img->Load("D:/workspace/cpp/darknet/data/roadsigns/images/stop/20.png");
    // auto color_model = JsColorModel::GetInstance();
    // color_model->GetColorRect(img, color_model->GetRedClassifyIndex(), 0.2);
}
void train_colors_model()
{
    auto model = std::make_shared<ColorModel>();
    model->LoadFromIniFile("D:/workspace/cpp/darknet/data/colors/model.ini");
    model->Train();

    std::string dst_model_path = "D:/workspace/cpp/darknet/web/asset/assets/colors/models/colors.model.lastest";
    std::filesystem::remove(dst_model_path);
    std::filesystem::copy(model->GetModelPath(), dst_model_path);
}

void test_colors_model()
{
    auto model = std::make_shared<ColorModel>();
    model->LoadModelFromFile("D:/workspace/cpp/darknet/data/colors/models/colors.model.lastest");
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict(0xca, 0xde, 0xc5))) << std::endl;
    // std::cout << Utf8ToString(model->GetIndexClassify(model->Predict(175,183,172))) << std::endl;
}

void test_roadlines_model()
{
    auto model = std::make_shared<RoadLineModel>();
    model->LoadModelFromFile("D:/workspace/cpp/darknet/data/roadlines/models/roadlines.model.lastest");
    // std::cout << model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadlines/datasets/0_0.jpg", nullptr)) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadlines/images/1720070763795_7877.jpg", nullptr))) << std::endl;
}

void train_roadlines_gray_model()
{
    auto model = std::make_shared<RoadLineGrayModel>();
    model->LoadFromIniFile("D:/workspace/cpp/darknet/data/roadlines/model.ini");
    model->Train();
}

void train_roadsigns_model()
{
    auto model = std::make_shared<RoadSignModel>();
    model->LoadFromIniFile("D:/workspace/cpp/darknet/data/roadsigns/model.ini");
    model->Train();
}

void test_roadsigns_model()
{
    auto model = std::make_shared<RoadSignModel>();
    model->LoadModelFromFile("D:/workspace/cpp/darknet/data/roadsigns/models/roadsigns.model.lastest");
    // std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/images/right/20.png", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566866375_9913.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566899333_1133.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566964007_8460.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566992197_812.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566931662_678.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/roadsigns/datasets/images/1719566278916_832.jpg", nullptr))) << std::endl;
}

void train_goods_model()
{
    auto model = std::make_shared<GoodsModel>();
    // auto proxy = JsModelProxy(model.get());
    // proxy.SetRootDirectory("D:/workspace/cpp/darknet/data/goods");
    // proxy.SetTrainParams(1, true);
    // for (int i = 0; i < 2000; i++)
    // {
    //     std::cout << proxy.DoEpoch() << std::endl;
    // }

    // model->LoadFromIniFile("D:/workspace/cpp/darknet/data/goods/model.ini");
    // model->Train();
    // std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("D:/workspace/cpp/darknet/data/goods/images/goods/1.jpg", nullptr))) << std::endl;
}

void test_goods_model()
{
    auto model = std::make_shared<GoodsModel>();
    // std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("d:/workspace/cpp/darknet/data/goods/datasets/images/1719558231112_6121.jpg", nullptr)))<< std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("d:/workspace/cpp/darknet/data/goods/datasets/images/1719558246740_496.jpg", nullptr))) << std::endl;
    std::cout << Utf8ToString(model->GetIndexClassify(model->Predict("d:/workspace/cpp/darknet/data/goods/datasets/images/1719558246740_496.jpg", nullptr))) << std::endl;
}

void remove_directory(const std::filesystem::path &path)
{
    if (std::filesystem::exists(path) && std::filesystem::is_directory(path))
    {
        for (const auto &entry : std::filesystem::directory_iterator(path))
        {
            if (entry.is_directory())
            {
                remove_directory(entry.path()); // 递归删除子目录
            }
            else
            {
                std::filesystem::remove(entry.path()); // 删除文件
            }
        }
        std::filesystem::remove(path); // 删除目录自身
    }
}

void handle_color_dataset(const std::string filepath)
{
    std::ifstream ifs(filepath);
    std::ofstream ofs(filepath + ".tmp");
    std::string line;
    while (std::getline(ifs, line))
    {
        auto pos = line.find(" ");
        if (pos != std::string::npos)
        {
            auto color    = line.substr(0, pos);
            auto classify = line.substr(pos + 1);
            if (classify != reinterpret_cast<const char *>(u8R"(其它)"))
            {
                ofs << color << " " << classify << std::endl;
            }
        }
    }
    ifs.close();
    ofs.close();
    std::filesystem::remove(filepath);
    std::filesystem::rename(filepath + ".tmp", filepath);
}

void handle_dataset(const std::filesystem::path &src_dataset_directory, const std::filesystem::path &dst_dataset_directory, SoftMaxModel *model)
{
    model->LoadNet();
    std::string root_directory         = "D:/workspace/cpp/darknet/web/asset/assets";
    std::string virtual_root_directory = "/darknet";
    auto src_images_directory          = src_dataset_directory / "images";
    auto dst_images_directory          = dst_dataset_directory / "images";
    auto dst_auto_images_directory     = dst_dataset_directory / "auto";
    remove_directory(dst_images_directory);
    remove_directory(dst_auto_images_directory);
    std::filesystem::create_directories(dst_dataset_directory);
    std::filesystem::create_directories(dst_images_directory);
    std::filesystem::create_directories(dst_auto_images_directory);
    std::ifstream ifs(src_dataset_directory / "dataset.txt");
    std::ofstream ofs(dst_dataset_directory / "dataset.txt");

    std::unordered_map<std::string, int> classify_size_map;
    std::string line;
    while (ifs.good())
    {
        std::getline(ifs, line);
        if (line.empty()) continue;
        std::istringstream iss(line);
        std::string img_path;
        std::string classify;
        iss >> img_path >> classify;
        if (img_path.empty() || classify.empty()) continue;
        img_path                    = root_directory + img_path.substr(virtual_root_directory.length());
        auto classify_size          = classify_size_map[classify];
        auto filename               = classify + "_" + std::to_string(classify_size) + std::filesystem::path(img_path).extension().string();
        auto img_new_path           = (dst_images_directory / filename).lexically_normal();
        classify_size_map[classify] = classify_size + 1;
        auto src_img_path           = Utf8ToString(img_path);
        if (std::filesystem::exists(src_img_path))
        {
            auto dst_img_path = Utf8ToString(img_new_path.string());
            std::filesystem::remove(dst_img_path);
            std::filesystem::copy(src_img_path, dst_img_path);
            auto path = img_new_path.string();
            std::replace(path.begin(), path.end(), '\\', '/');
            ofs << path << " " << classify << std::endl;

            if (model != nullptr)
            {
                std::shared_ptr<DataImage> img = std::make_shared<DataImage>();
                if (img->Load(img_path))
                {
                    img = model->HandleInputImage(img);
                    img->Save((dst_auto_images_directory / filename).string());
                }
            }
        }
    }
}

void train_roadlines_near_direction_model()
{
    std::string root_directory = "D:/workspace/cpp/darknet/data/roadlines_near_direction";
    auto model                 = std::make_shared<RoadLineNearDirectionModel>();
    // std::filesystem::remove(root_directory + "/models/" + model->GetDefaultModelFileName());
    // std::filesystem::remove(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    handle_dataset(model->GetRootDirectory() + "/datasets", root_directory + "/datasets", model.get());
    model->SetDataSetPath(root_directory + "/datasets/dataset.txt");
    model->LoadModelFromFile(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    model->SetMaxEpcohs(1000);
    model->Train();
}

void test_roadlines_near_direction_model()
{
    auto model = std::make_shared<RoadLineNearDirectionModel>();
    model->LoadModelFromFile(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    auto classify_index = model->Predict((const char*)(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/右转_14.jpg)"), nullptr);
    std::cout << Utf8ToString(model->GetIndexClassify(classify_index)) << std::endl;
}

void train_roadlines_far_direction_model()
{
    std::string root_directory = "D:/workspace/cpp/darknet/data/roadlines_far_direction";
    auto model                 = std::make_shared<RoadLineFarDirectionModel>();
    // std::filesystem::remove(root_directory + "/models/" + model->GetDefaultModelFileName());
    // std::filesystem::remove(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    handle_dataset(model->GetRootDirectory() + "/datasets", root_directory + "/datasets", model.get());
    model->LoadModelFromFile(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    model->SetMaxEpcohs(500);
    model->SetDataSetPath(root_directory + "/datasets/dataset.txt");
    model->Train();
}

void train_roadlines_model()
{
    std::string root_directory = "D:/workspace/cpp/darknet/data/roadlines";
    auto model                 = std::make_shared<RoadLineModel>();
    // std::filesystem::remove(root_directory + "/models/" + model->GetDefaultModelFileName());
    // std::filesystem::remove(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    handle_dataset(model->GetRootDirectory() + "/datasets", root_directory + "/datasets", model.get());
    model->LoadModelFromFile(model->GetRootDirectory() + "/models/" + model->GetDefaultModelFileName());
    model->SetMaxEpcohs(500);
    model->SetDataSetPath(root_directory + "/datasets/dataset.txt");
    model->Train();
}

void train_map_color_model(const std::string &map_name = "map")
{
    auto model = std::make_shared<MapColorModel>(map_name);
    model->Train();
}

void test_map_color_model()
{
    SmartCar smartcar;
    auto img = std::make_shared<DataImage>();
    img->Load(reinterpret_cast<const char *>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/缓行_9.jpg)"));
    smartcar.GetRoadLineClassify(img, "map");
}

void test()
{
    int width  = 0;
    int height = 0;
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/右转_14.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/右转_16.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/直行_2.jpg)"), &width, &height);
    auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/缓行_1.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/缓行_18.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadlines_near_direction/datasets/images/禁止通行_25.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char*>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadsigns/datasets/images/1721098942878_40.jpg)"), &width, &height);
    // auto pixels = DataImage::LoadRGB(reinterpret_cast<const char *>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadsigns/datasets/images/1721098761215_664.jpg)"), &width, &height);
    RoadLineUtils::ScaleGray(pixels, width, height, 32, 24);
    // RoadLineUtils::GetRedRectDatas(pixels, width, height, 0.2f, 32, 24);
}

void esp_main();

#ifndef __EMSCRIPTEN__
int main(int argc, char *argv[])
{
    // test();
    test_roadlines_near_direction_model();
    // esp_main();
    // test_map_color_model();
    // handle_color_dataset("D:/workspace/cpp/darknet/web/asset/assets/colors/datasets/map.colors.dataset.colors");
    // train_map_color_model();
    // train_roadlines_near_direction_model();
    // train_roadlines_far_direction_model();
    // train_roadlines_model();
    // std::setlocale(LC_ALL, ""); // 设置当前区域和语言环境

    // SmartCar smartcar;
    // auto img = std::make_shared<DataImage>();
    // img->Load("D:/workspace/cpp/darknet/data/roadlines/images/1720070687040_4696.jpg");
    // smartcar.GetRoadLineClassify(img);
    // handle_dataset();

    // train_goods_model();
    // test_goods_model();

    // JsModelProxy model(RoadSignModel::GetInstance());
    // model.DownloadDataSet();

    // train_roadsigns_model();
    // test_roadsigns_model();

    // train_colors_model();
    // test_colors_model();

    // train_roadlines_model();
    // test_roadlines_model();
    // test_js();

    // test_darknet();

    // train_softmax_qrcode();
    // test_softmax_qrcode();
    // train_yolo_qrcode();
    // predict_yolo_qrcode();

    // train_yolo();
    // predict_yolo();
    // test_yolo();

    // DataImage::Test();

    // train_softmax();
    // predict_softmax();
    // test_softmax();
    return 0;
}
#else
#include "JsFetch.h"
int main(int argc, char *argv[])
{
    // JSFetch();
}
#endif
